/*
 *MIT License
 *
 *Copyright (c) 2019 chenshuai cs4380@163.com
 *
 *Permission is hereby granted, free of charge, to any person obtaining a copy
 *of this software and associated documentation files (the "Software"), to deal
 *in the Software without restriction, including without limitation the rights
 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *copies of the Software, and to permit persons to whom the Software is
 *furnished to do so, subject to the following conditions:
 *
 *The above copyright notice and this permission notice shall be included in all
 *copies or substantial portions of the Software.
 *
 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *SOFTWARE.
 */

package com.cs.cslc.auth.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.cs.cslc.auth.bean.JWTUserBean;
import com.cs.cslc.common.constant.JwtUserConstant;

import java.util.Date;
import java.util.List;

/**
 * JWTUtil JWT工具类.
 * <p>
 * jwt操作工具类：生成签名、验证token
 * </p>
 *
 * @author cs4380 https://gitee.com/xhbug_cs4380  cs4380@163.com
 * @version 1.0
 * @since 2019-05-06 09:27
 */
public class JWTUtil {

    /**
     * 生成签名
     *
     * @param user       jwt用户信息
     * @param secret     密钥
     * @param expireTime 失效时间(单位：毫秒)
     * @return 生成签名token
     */
    public static String sign(JWTUserBean user, String secret, long expireTime) {
        Date expire = new Date(System.currentTimeMillis() + expireTime);
        Algorithm algorithm = Algorithm.HMAC256(secret);
        String[] roles = new String[user.getRoles().size()];
        user.getRoles().toArray(roles);
        String[] depts = new String[user.getDepts().size()];
        user.getDepts().toArray(depts);
        return JWT.create()
                .withClaim(JwtUserConstant.JWT_KEY_USER_ACCOUNT, user.getAccount())
                .withClaim(JwtUserConstant.JWT_KEY_USER_ID, user.getUserId())
                .withClaim(JwtUserConstant.JWT_KEY_NAME, user.getName())
                .withClaim(JwtUserConstant.JWT_KEY_TENANT_ID, user.getTenantId())
                .withArrayClaim(JwtUserConstant.JWT_KEY_USER_ROLES, roles)
                .withArrayClaim(JwtUserConstant.JWT_KEY_DEPARTS, depts)
                .withClaim(JwtUserConstant.JWT_KEY_USER_IS_ADMIN, user.getIsSuperAdmin())
                .withExpiresAt(expire)
                .sign(algorithm);
    }

    /**
     * 获得token中的信息，无需secret解密也能获得
     *
     * @return
     */
    public static String getJwtValue(String token, String key) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim(key).asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获得token中的信息
     *
     * @return token中包含的UserBean信息
     */
    public static JWTUserBean getUserBeanByToken(String token) {
        JWTUserBean userBean = new JWTUserBean();
        try {
            DecodedJWT jwt = JWT.decode(token);
            userBean.setAccount(jwt.getClaim(JwtUserConstant.JWT_KEY_USER_ACCOUNT).asString());
            userBean.setName(jwt.getClaim(JwtUserConstant.JWT_KEY_NAME).asString());
            userBean.setUserId(jwt.getClaim(JwtUserConstant.JWT_KEY_USER_ID).asString());
            userBean.setTenantId(jwt.getClaim(JwtUserConstant.JWT_KEY_TENANT_ID).asString());

            List<String> roles = jwt.getClaim(JwtUserConstant.JWT_KEY_USER_ROLES).asList(String.class);
            userBean.setRoles(roles);

            List<String> depts = jwt.getClaim(JwtUserConstant.JWT_KEY_DEPARTS).asList(String.class);
            userBean.setDepts(depts);

            userBean.setIsSuperAdmin(jwt.getClaim(JwtUserConstant.JWT_KEY_USER_IS_ADMIN).asInt());
        } catch (JWTDecodeException e) {
            e.printStackTrace();
        }
        return userBean;
    }

    /**
     * 获取签名密钥
     * <p>
     * jwt签名密钥，有账号和密码组成
     * </p>
     *
     * @param user 用户信息
     * @return 获取用户签名密钥
     */
    public static String getSecret(JWTUserBean user) {
        return user.getAccount() + user.getPassword();
    }
}